/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 combat_object_model.cpp

	$Header: /heroes4/combat_object_model.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "combat_object_model.h"

#include "obstacle_type.h"
#include "streambuf_operators.h"

// --------------------------------------------------------------------------
// Unnamed namespace
// --------------------------------------------------------------------------

namespace
{
	int const k_current_format_version = 2;

} // Unnamed namespace

// --------------------------------------------------------------------------
// t_combat_object_model_base members
// --------------------------------------------------------------------------

bool t_combat_object_model_root::m_combat_has_changed = false;

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_combat_object_model_root::~t_combat_object_model_root()
{
}

// --------------------------------------------------------------------------
// t_combat_object_model_24 members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_combat_object_model_base::read( std::streambuf & stream )
{
	int new_columns;
	int new_rows;
	int new_height;
	int new_frames_per_second;
	bool new_underlay;

	try
	{
		int version = get< t_uint16 >( stream );
		if ( version < 0 || version > k_current_format_version )
			return false;

		if (version < 2)
		{
			new_rows = get< t_uint8 >( stream );
			new_columns = new_rows;
		}
		else
		{
			new_rows = get<t_uint8>( stream );
			new_columns = get<t_uint8>( stream );
		}
		new_height = get< t_uint8 >( stream );
		new_frames_per_second = get< t_uint8 >( stream );
		new_underlay = get< t_uint8 >( stream ) != 0;
		if (version < 1)
		{
			m_blocks_movement = false;
			m_can_be_destroyed = false;
			m_can_be_summoned = false;
			m_hinders_movement = false;
			m_obscures_vision = false;
			m_type = k_obstacle_special;
		}
		else
		{
			std::string     type_string;
			t_obstacle_type new_type;

			m_blocks_movement = get<bool>( stream );
			m_can_be_destroyed = get<bool>( stream );
			m_can_be_summoned = get<bool>( stream );
			m_hinders_movement = get<bool>( stream );
			m_obscures_vision = get<bool>( stream );
			m_type = t_obstacle_type( get<t_int16>( stream ) );
			if (m_type < 0 || m_type >= k_obstacle_type_count)
				m_type = k_obstacle_special; // this is a hack, since garbage got written out.
			read_string16( stream, type_string );
			if (stricmp( get_obstacle_keyword( m_type ).c_str(), type_string.c_str() ) != 0 )
			{
				new_type = get_obstacle_type( type_string );
				if (new_type != k_obstacle_none)
					m_type = new_type;
			}
		}
	}
	catch ( t_streambuf_read_failure const & )
	{
		return false;
	}

	set_footprint_rows( new_rows );
	set_footprint_columns( new_columns );
	set_height( new_height );
	set_frames_per_second( new_frames_per_second );
	set_is_underlay( new_underlay );

	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_combat_object_model_base::write( std::streambuf & stream ) const
{
	try
	{
		put< t_uint16 >( stream, k_current_format_version );
		put< t_uint8 >( stream, m_footprint_size.row );
		put< t_uint8 >( stream, m_footprint_size.column );
		put< t_uint8 >( stream, get_height() );
		put< t_uint8 >( stream, get_frames_per_second() );
		put< t_uint8 >( stream, is_underlay() );
		put<bool>( stream, m_blocks_movement );
		put<bool>( stream, m_can_be_destroyed );
		put<bool>( stream, m_can_be_summoned );
		put<bool>( stream, m_hinders_movement );
		put<bool>( stream, m_obscures_vision );
		put<t_int16>( stream, m_type );
		write_string16( stream, get_obstacle_keyword( m_type ) );
	}
	catch ( t_streambuf_write_failure const & )
	{
		return false;
	}
	return true;
}


// --------------------------------------------------------------------------
// t_combat_object_model_24 members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_combat_object_model_24::read( std::streambuf & stream )
{
	if (!t_combat_object_model_base::read( stream ))
		return false;
	if ( !t_image_sequence_24::read( stream ) )
		return false;
	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_combat_object_model_24::write( std::streambuf & stream ) const
{
	if (!t_combat_object_model_base::write( stream ))
		return false;
	return t_image_sequence_24::write( stream );
}


// --------------------------------------------------------------------------
// t_resource_traits< t_combat_object_model_24 > members
// --------------------------------------------------------------------------
char const t_resource_traits< t_combat_object_model_base >::prefix[] = "combat_object";

char const t_resource_traits< t_combat_object_model_24 >::prefix[] = "combat_object";

char const t_resource_traits< t_combat_object_model_24 >::extension[] = "psd";
